home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\STATUS.C < prev    next >
C/C++ Source or Header  |  1995-01-04  |  28KB  |  1,249 lines

  1. /*
  2.  * status.c: handles the status line updating, etc for IRCII 
  3.  *
  4.  * Written By Michael Sandrof
  5.  *
  6.  * Copyright(c) 1990 
  7.  *
  8.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  9.  */
  10.  
  11. #ifndef lint
  12. static    char    rcsid[] = "@(#)$Id: status.c,v 1.17 1994/07/02 02:32:13 mrg Stab $";
  13. #endif
  14.  
  15. #include "irc.h"
  16.  
  17. #include "term.h"
  18. #include "status.h"
  19. #include "server.h"
  20. #include "vars.h"
  21. #include "hook.h"
  22. #include "input.h"
  23. #include "edit.h"
  24. #include "window.h"
  25. #include "screen.h"
  26. #include "mail.h"
  27. #include "output.h"
  28. #include "names.h"
  29. #include "ircaux.h"
  30. #include "translat.h"
  31.  
  32. extern    time_t    time();
  33.  
  34. extern    char    *update_clock();
  35. static    char    *convert_format();
  36. static    char    *status_nickname();
  37. static    char    *status_query_nick();
  38. static    char    *status_right_justify();
  39. static    char    *status_chanop();
  40. static    char    *status_channel();
  41. static    char    *status_server();
  42. static    char    *status_mode();
  43. static    char    *status_umode();
  44. static    char    *status_insert_mode();
  45. static    char    *status_overwrite_mode();
  46. static    char    *status_away();
  47. static    char    *status_oper();
  48. static    char    *status_user0();
  49. static    char    *status_user1();
  50. static    char    *status_user2();
  51. static    char    *status_user3();
  52. static    char    *status_hold();
  53. static    char    *status_version();
  54. static    char    *status_clock();
  55. static    char    *status_hold_lines();
  56. static    char    *status_window();
  57. static    char    *status_mail();
  58. static    char    *status_refnum();
  59. static    char    *status_null_function();
  60. static    char    *status_notify_windows();
  61. static    void    status_make_printable __P((unsigned char *, int));
  62.  
  63. /*
  64.  * Maximum number of "%" expressions in a status line format.  If you change
  65.  * this number, you must manually change the sprintf() in make_status 
  66.  */
  67. #define MAX_FUNCTIONS 33
  68.  
  69. /* The format statements to build each portion of the status line */
  70. static    char    *mode_format = (char *) 0;
  71. static    char    *umode_format = (char *) 0;
  72. static    char    *status_format = (char *) 0;
  73. static    char    *query_format = (char *) 0;
  74. static    char    *clock_format = (char *) 0;
  75. static    char    *hold_lines_format = (char *) 0;
  76. static    char    *channel_format = (char *) 0;
  77. static    char    *mail_format = (char *) 0;
  78. static    char    *server_format = (char *) 0;
  79. static    char    *notify_format = (char *) 0;
  80.  
  81. /*
  82.  * status_func: The list of status line function in the proper order for
  83.  3 display.  This list is set in convert_format() 
  84.  */
  85. static    char    *(*status_func[MAX_FUNCTIONS]) ();
  86.  
  87. /* func_cnt: the number of status line functions assigned */
  88. static    int    func_cnt = 0;
  89.  
  90. static    int    alarm_hours,        /* hour setting for alarm in 24 hour time */
  91.         alarm_minutes;        /* minute setting for alarm */
  92.  
  93. /* Stuff for the alarm */
  94. static    struct itimerval clock_timer = { { 10L, 0L }, { 1L, 0L } };
  95. static    struct itimerval off_timer = { { 0L, 0L }, { 0L, 0L } };
  96.  
  97. static    RETSIGTYPE alarmed __P((int));
  98.  
  99. /* alarmed: This is called whenever a SIGALRM is received and the alarm is on */
  100. static    RETSIGTYPE
  101. alarmed(unused)
  102.     int    unused;
  103. {
  104.     say("The time is %s", update_clock(GET_TIME));
  105.     term_beep();
  106.     term_beep();
  107.     term_beep();
  108. }
  109.  
  110. /*
  111.  * alarm_switch: turns on and off the alarm display.  Sets the system timer
  112.  * and sets up a signal to trap SIGALRMs.  If flag is 1, the alarmed()
  113.  * routine will be activated every 10 seconds or so.  If flag is 0, the timer
  114.  * and signal stuff are reset 
  115.  */
  116. static    void
  117. alarm_switch(flag)
  118.     int    flag;
  119. {
  120. #ifndef _Windows
  121.     static    int    alarm_on = 0;
  122.  
  123.     if (flag)
  124.     {
  125.         if (!alarm_on)
  126.         {
  127.             setitimer(ITIMER_REAL, &clock_timer,
  128.                 (struct itimerval *) 0);
  129.             (void) MY_SIGNAL(SIGALRM, alarmed, 0);
  130.             alarm_on = 1;
  131.         }
  132.     }
  133.     else if (alarm_on)
  134.     {
  135.         setitimer(ITIMER_REAL, &off_timer, (struct itimerval *) 0);
  136.         (void) MY_SIGNAL(SIGALRM, SIG_IGN, 0);
  137.         alarm_on = 0;
  138.     }
  139. #endif
  140. }
  141.  
  142. /*
  143.  * set_alarm: given an input string, this checks it's validity as a clock
  144.  * type time thingy.  It accepts two time formats.  The first is the HH:MM:XM
  145.  * format where HH is between 1 and 12, MM is between 0 and 59, and XM is
  146.  * either AM or PM.  The second is the HH:MM format where HH is between 0 and
  147.  * 23 and MM is between 0 and 59.  This routine also looks for one special
  148.  * case, "OFF", which sets the alarm string to null 
  149.  */
  150. void
  151. set_alarm(str)
  152.     char    *str;
  153. {
  154.     char    hours[10],
  155.         minutes[10],
  156.         merid[3];
  157.     char    time_str[10];
  158.     int    c,
  159.         h,
  160.         m,
  161.         min_hours,
  162.         max_hours;
  163.  
  164.     if (str == (char *) 0)
  165.     {
  166.         alarm_switch(0);
  167.         return;
  168.     }
  169.     if (!my_stricmp(str, var_settings[OFF]))
  170.     {
  171.         set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  172.         alarm_switch(0);
  173.         return;
  174.     }
  175.  
  176.     c = sscanf(str, " %2[^:]:%2[^paPA]%2s ", hours, minutes, merid);
  177.     switch (c)
  178.     {
  179.     case 2:
  180.         min_hours = 0;
  181.         max_hours = 23;
  182.         break;
  183.     case 3:
  184.         min_hours = 1;
  185.         max_hours = 12;
  186.         upper(merid);
  187.         break;
  188.     default:
  189.         say("CLOCK_ALARM: Bad time format.");
  190.         set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  191.         return;
  192.     }
  193.  
  194.     h = atoi(hours);
  195.     m = atoi(minutes);
  196.     if (h >= min_hours && h <= max_hours && isdigit(hours[0]) &&
  197.         (isdigit(hours[1]) || hours[1] == (char) 0))
  198.     {
  199.         if (m >= 0 && m <= 59 && isdigit(minutes[0]) &&
  200.                 isdigit(minutes[1]))
  201.         {
  202.             alarm_minutes = m;
  203.             alarm_hours = h;
  204.             if (max_hours == 12)
  205.             {
  206.                 if (merid[0] != 'A')
  207.                 {
  208.                     if (merid[0] == 'P')
  209.                     {
  210.                         if (h != 12)
  211.                             alarm_hours += 12;
  212.                     }
  213.                     else
  214.                     {
  215.     say("CLOCK_ALARM: alarm time must end with either \"AM\" or \"PM\"");
  216.     set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  217.                     }
  218.                 }
  219.                 else
  220.                 {
  221.                     if (h == 12)
  222.                         alarm_hours = 0;
  223.                 }
  224.                 if (merid[1] == 'M')
  225.                 {
  226.                     sprintf(time_str, "%02d:%02d%s", h, m,
  227.                         merid);
  228.                     set_string_var(CLOCK_ALARM_VAR,
  229.                         time_str);
  230.                 }
  231.                 else
  232.                 {
  233.     say("CLOCK_ALARM: alarm time must end with either \"AM\" or \"PM\"");
  234.     set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  235.                 }
  236.             }
  237.             else
  238.             {
  239.                 sprintf(time_str, "%02d:%02d", h, m);
  240.                 set_string_var(CLOCK_ALARM_VAR, time_str);
  241.             }
  242.         }
  243.         else
  244.         {
  245.     say("CLOCK_ALARM: alarm minutes value must be between 0 and 59.");
  246.     set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  247.         }
  248.     }
  249.     else
  250.     {
  251.         say("CLOCK_ALARM: alarm hour value must be between %d and %d.",
  252.             min_hours, max_hours);
  253.         set_string_var(CLOCK_ALARM_VAR, (char *) 0);
  254.     }
  255. }
  256.  
  257. /* update_clock: figures out the current time and returns it in a nice format */
  258. char    *
  259. update_clock(flag)
  260.     int    flag;
  261. {
  262.     static    char    time_str[10];
  263.     static    int    min = -1,
  264.             hour = -1;
  265.     struct tm    *time_val;
  266.     char    *merid;
  267.     time_t    t;
  268.  
  269.     t = time(0);
  270.     time_val = localtime(&t);
  271.     if (get_string_var(CLOCK_ALARM_VAR))
  272.     {
  273.         if ((time_val->tm_hour == alarm_hours) &&
  274.                 (time_val->tm_min == alarm_minutes))
  275.             alarm_switch(1);
  276.         else
  277.             alarm_switch(0);
  278.     }
  279.     if (flag == RESET_TIME || time_val->tm_min != min || time_val->tm_hour != hour)
  280.     {
  281.         int    tmp_hour,
  282.             tmp_min,
  283.             server;
  284.  
  285.         tmp_hour = time_val->tm_hour;
  286.         tmp_min = time_val->tm_min;
  287.  
  288.         if (get_int_var(CLOCK_24HOUR_VAR))
  289.             merid = empty_string;
  290.         else
  291.         {
  292.             if (time_val->tm_hour < 12)
  293.                 merid = "AM";
  294.             else
  295.                 merid = "PM";
  296.             if (time_val->tm_hour > 12)
  297.                 time_val->tm_hour -= 12;
  298.             else if (time_val->tm_hour == 0)
  299.                 time_val->tm_hour = 12;
  300.         }
  301.         server = from_server;
  302.         from_server = primary_server;
  303.         sprintf(time_str, "%02d:%02d%s", time_val->tm_hour, time_val->tm_min, merid);
  304.         if (tmp_min != min || tmp_hour != hour)
  305.         {
  306.             hour = tmp_hour;
  307.             min = tmp_min;
  308.             do_hook(TIMER_LIST, "%s", time_str);
  309.         }
  310.         do_hook(IDLE_LIST, "%ld", (t - idle_time) / 60L);
  311.         from_server = server;
  312.         return (time_str);
  313.     }
  314.     if (flag == GET_TIME)
  315.         return(time_str);
  316.     else
  317.         return ((char *) 0);
  318. }
  319.  
  320. /*ARGSUSED*/
  321. void
  322. reset_clock(unused)
  323.     char    *unused;
  324. {
  325.     update_clock(RESET_TIME);
  326.     update_all_status();
  327. }
  328.  
  329. /*
  330.  * convert_sub_format: This is used to convert the formats of the
  331.  * sub-portions of the status line to a format statement specially designed
  332.  * for that sub-portions.  convert_sub_format looks for a single occurence of
  333.  * %c (where c is passed to the function). When found, it is replaced by "%s"
  334.  * for use is a sprintf.  All other occurences of % followed by any other
  335.  * character are left unchanged.  Only the first occurence of %c is
  336.  * converted, all subsequence occurences are left unchanged.  This routine
  337.  * mallocs the returned string. 
  338.  */
  339. static    char    *
  340. convert_sub_format(format, c)
  341.     char    *format;
  342.     char    c;
  343. {
  344.     define_big_buffer(buffer);
  345.     static    char    bletch[] = "%% ";
  346.     char    *ptr = (char *) 0;
  347.     int    dont_got_it = 1;
  348.  
  349.     if (format == (char *) 0)
  350.         return ((char *) 0);
  351.     *buffer = (char) 0;
  352.     while (format)
  353.     {
  354.         if ((ptr = (char *) index(format, '%')) != NULL)
  355.         {
  356.             *ptr = (char) 0;
  357.             strmcat(buffer, format, BIG_BUFFER_SIZE);
  358.             *(ptr++) = '%';
  359.             if ((*ptr == c) && dont_got_it)
  360.             {
  361.                 dont_got_it = 0;
  362.                 strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  363.             }
  364.             else
  365.             {
  366.                 bletch[2] = *ptr;
  367.                 strmcat(buffer, bletch, BIG_BUFFER_SIZE);
  368.             }
  369.             ptr++;
  370.         }
  371.         else
  372.             strmcat(buffer, format, BIG_BUFFER_SIZE);
  373.         format = ptr;
  374.     }
  375.     malloc_strcpy(&ptr, buffer);
  376.     free_big_buffer(buffer);
  377.     return (ptr);
  378. }
  379.  
  380. static    char    *
  381. convert_format(str)
  382.     char    *str;
  383. {
  384.     define_big_buffer(buffer);
  385.     char    *ptr,
  386.         *format,
  387.         *malloc_ptr = (char *) 0;
  388.  
  389.     format = get_string_var(STATUS_FORMAT_VAR);
  390.     *buffer = (char) 0;
  391.     while (format)
  392.     {
  393.         if ((ptr = (char *) index(format, '%')) != NULL)
  394.         {
  395.             *ptr = (char) 0;
  396.             strmcat(buffer, format, BIG_BUFFER_SIZE);
  397.             *(ptr++) = '%';
  398.             if (func_cnt < MAX_FUNCTIONS)
  399.             {
  400.                 switch (*(ptr++))
  401.                 {
  402.                 case '%':
  403.                     strmcat(buffer, "%", BIG_BUFFER_SIZE);
  404.                     break;
  405.                 case 'N':
  406.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  407.                     status_func[func_cnt++] =
  408.                         status_nickname;
  409.                     break;
  410.                 case '>':
  411.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  412.                     status_func[func_cnt++] = status_right_justify;
  413.                     break;
  414.                 case 'Q':
  415.                     new_free(&query_format);
  416.                     query_format =
  417.         convert_sub_format(get_string_var(STATUS_QUERY_VAR), 'Q');
  418.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  419.                     status_func[func_cnt++] =
  420.                         status_query_nick;
  421.                     break;
  422.                 case 'F':
  423.                     new_free(¬ify_format);
  424.                     notify_format = 
  425.         convert_sub_format(get_string_var(STATUS_NOTIFY_VAR), 'F');
  426.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  427.                     status_func[func_cnt++] =
  428.                         status_notify_windows;
  429.                     break;
  430.                 case '@':
  431.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  432.                     status_func[func_cnt++] = status_chanop;
  433.                     break;
  434.                 case 'C':
  435.                     new_free(&channel_format);
  436.                     channel_format =
  437.         convert_sub_format(get_string_var(STATUS_CHANNEL_VAR), 'C');
  438.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  439.                     status_func[func_cnt++]= status_channel;
  440.                     break;
  441.                 case 'S':
  442.                     new_free(&server_format);
  443.                     server_format =
  444.         convert_sub_format(get_string_var(STATUS_SERVER_VAR), 'S');
  445.                     strmcat(buffer,"%s",BIG_BUFFER_SIZE);
  446.                     status_func[func_cnt++] = status_server;
  447.                     break;
  448.                 case '+':
  449.                     new_free(&mode_format);
  450.                     mode_format =
  451.         convert_sub_format(get_string_var(STATUS_MODE_VAR), '+');
  452.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  453.                     status_func[func_cnt++] = status_mode;
  454.                     break;
  455.                 case '#':
  456.                     new_free(&umode_format);
  457.                     umode_format =
  458.         convert_sub_format(get_string_var(STATUS_UMODE_VAR), '#');
  459.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  460.                     status_func[func_cnt++] = status_umode;
  461.                     break;
  462.                 case 'M':
  463.                     new_free(&mail_format);
  464.                     mail_format =
  465.         convert_sub_format(get_string_var(STATUS_MAIL_VAR), 'M');
  466.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  467.                     status_func[func_cnt++] = status_mail;
  468.                     break;
  469.                 case 'I':
  470.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  471.                     status_func[func_cnt++] =
  472.                         status_insert_mode;
  473.                     break;
  474.                 case 'O':
  475.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  476.                     status_func[func_cnt++] =
  477.                         status_overwrite_mode;
  478.                     break;
  479.                 case 'A':
  480.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  481.                     status_func[func_cnt++] = status_away;
  482.                     break;
  483.                 case 'V':
  484.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  485.                     status_func[func_cnt++] = status_version;
  486.                     break;
  487.                 case 'R':
  488.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  489.                     status_func[func_cnt++] = status_refnum;
  490.                     break;
  491.                 case 'T':
  492.                     new_free(&clock_format);
  493.                     clock_format =
  494.         convert_sub_format(get_string_var(STATUS_CLOCK_VAR), 'T');
  495.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  496.                     status_func[func_cnt++] = status_clock;
  497.                     break;
  498.                 case 'U':
  499.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  500.                     status_func[func_cnt++] = status_user0;
  501.                     break;
  502.                 case 'H':
  503.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  504.                     status_func[func_cnt++] = status_hold;
  505.                     break;
  506.                 case 'B':
  507.                     new_free(&hold_lines_format);
  508.                     hold_lines_format =
  509.         convert_sub_format(get_string_var(STATUS_HOLD_LINES_VAR), 'B');
  510.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  511.                     status_func[func_cnt++] =
  512.                         status_hold_lines;
  513.                     break;
  514.                 case '*':
  515.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  516.                     status_func[func_cnt++] = status_oper;
  517.                     break;
  518.                 case 'W':
  519.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  520.                     status_func[func_cnt++] = status_window;
  521.                     break;
  522.                 case 'X':
  523.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  524.                     status_func[func_cnt++] = status_user1;
  525.                     break;
  526.                 case 'Y':
  527.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  528.                     status_func[func_cnt++] = status_user2;
  529.                     break;
  530.                 case 'Z':
  531.                     strmcat(buffer, "%s", BIG_BUFFER_SIZE);
  532.                     status_func[func_cnt++] = status_user3;
  533.                     break;
  534.         /* no default..?? - phone, jan 1993 */
  535.         /* empty is a good default -lynx, mar 93 */
  536.                 }
  537.             }
  538.             else
  539.                 ptr++;
  540.         }
  541.         else
  542.             strmcat(buffer, format, BIG_BUFFER_SIZE);
  543.         format = ptr;
  544.     }
  545.     /* this frees the old str first */
  546.     malloc_strcpy(&malloc_ptr, buffer);
  547.     free_big_buffer(buffer);
  548.     return (malloc_ptr);
  549. }
  550.  
  551. void
  552. build_status(format)
  553.     char    *format;
  554. {
  555.     int    i;
  556.  
  557.     new_free(&status_format);
  558.     func_cnt = 0;
  559.     if ((format = get_string_var(STATUS_FORMAT_VAR)) != NULL)
  560.         status_format = convert_format(format);    /* convert_format
  561.                              * mallocs for
  562.                              * us */
  563.     for (i = func_cnt; i < MAX_FUNCTIONS; i++)
  564.         status_func[i] = status_null_function;
  565.     update_all_status();
  566. }
  567.  
  568. void
  569. make_status(window)
  570.     Window    *window;
  571. {
  572.     int    i,
  573.     len,
  574.     RJustifyPos = -1,
  575.     RealPosition;
  576.     define_big_buffer(buffer);
  577.     char    *func_value[MAX_FUNCTIONS];
  578.     Screen *old_current_screen;
  579.     old_current_screen = current_screen;
  580.     set_current_screen(window->screen);
  581.  
  582.     if (!dumb && status_format)
  583.     {
  584.         for (i = 0; i < MAX_FUNCTIONS; i++)
  585.             func_value[i] = (status_func[i]) (window);
  586.         buffer[0] = REV_TOG;
  587.         sprintf(buffer+1, status_format, func_value[0], func_value[1],
  588.             func_value[2], func_value[3], func_value[4], func_value[5],
  589.             func_value[6], func_value[7], func_value[8], func_value[9],
  590.             func_value[10], func_value[11], func_value[12],
  591.             func_value[13], func_value[14], func_value[15],
  592.             func_value[16], func_value[17], func_value[18],
  593.             func_value[19], func_value[20], func_value[21],
  594.             func_value[22], func_value[23], func_value[24],
  595.             func_value[25], func_value[26], func_value[27],
  596.             func_value[28], func_value[29], func_value[30],
  597.             func_value[31], func_value[32]);
  598.         for (i = 0; i < MAX_FUNCTIONS; i++)
  599.             new_free(&(func_value[i]));
  600.  
  601.         /*  Patched 26-Mar-93 by Aiken
  602.          *  make_window now right-justifies everything after a %>
  603.          *  it's also more efficient.
  604.          */
  605.  
  606.         RealPosition = 0;
  607.         for (i = 0; buffer[i]; i++)
  608.             /* formfeed is a marker for left/right border */
  609.             if (buffer[i] == '\f')
  610.             {
  611.                 RJustifyPos = i;
  612.             }
  613.             else if (buffer[i] != REV_TOG && buffer[i] != UND_TOG && buffer[i] != ALL_OFF && buffer[i] != BOLD_TOG)
  614.             {
  615.                 if (RealPosition == CO)
  616.                 {
  617.                     buffer[i] = '\0';
  618.                     break;
  619.                 }
  620.                 RealPosition++;
  621.             }
  622.  
  623.         /* note that i points to the nul, RealPosition is vis.chars */
  624.  
  625.         if (RJustifyPos == -1)
  626.         {
  627.             RJustifyPos = i;
  628.         }
  629.         else
  630.         {
  631.             /* get rid of the marker */
  632.             strcpy(&buffer[RJustifyPos], &buffer[RJustifyPos+1]);
  633.             i--;
  634.         }
  635.  
  636.         if (get_int_var(FULL_STATUS_LINE_VAR))
  637.         {
  638.             int    diff;
  639.             char    c;
  640.  
  641.             if (RJustifyPos == 0)
  642.                 c = ' ';
  643.             else
  644.                 c = buffer[RJustifyPos - 1];
  645.  
  646.             diff = CO - RealPosition;
  647.  
  648.             for ( ; i >= RJustifyPos; i--)
  649.                 buffer[i + diff] = buffer[i];
  650.  
  651.             for (i++ ; diff > 0 ; diff--, i++)
  652.                 buffer[i] = c;
  653.         }
  654.  
  655.         len = strlen(buffer);
  656.         buffer[len] = ALL_OFF;
  657.         buffer[len+1] = (char) 0;
  658.  
  659.         status_make_printable(buffer, len);
  660.  
  661.     /*
  662.      * Thanks to Max Bell (mbell@cie.uoregon.edu) for info about TVI
  663.      * terminals and the sg terminal capability 
  664.      */
  665.         RealPosition = 0;
  666. #ifndef _Windows
  667.         if (window->status_line && (SG == -1))
  668.         {
  669.             for (i = 0; buffer[i] && window->status_line[i]; i++)
  670.             {
  671.                 if (buffer[i] != window->status_line[i])
  672.                     break;
  673.                 if (buffer[i] != REV_TOG && buffer[i] != UND_TOG && buffer[i] != ALL_OFF && buffer[i] != BOLD_TOG)
  674.                     RealPosition++;
  675.             }
  676.         }
  677.         else
  678. #endif _Windows
  679.             i = 0;
  680.         if ((len = strlen(buffer + i)) || buffer[i] || !window->status_line || window->status_line[i])
  681.         {
  682.             term_move_cursor(RealPosition, window->bottom);
  683.             term_status_on();
  684.             output_line(buffer, NULL, i);
  685.             cursor_in_display();
  686.             if (term_clear_to_eol())
  687.                 term_space_erase(len);
  688.             term_status_off();
  689.             malloc_strcpy(&window->status_line, buffer);
  690.         }
  691.     }
  692.     cursor_to_input();
  693.     set_current_screen(old_current_screen);
  694.     free_big_buffer(buffer);
  695. }
  696.  
  697. static    char    *
  698. status_nickname(window)
  699.     Window    *window;
  700. {
  701.     char    *ptr = (char *) 0;
  702.  
  703.     if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR)
  704.         && (!window->current_channel) &&
  705.         (window->screen->current_window != window))
  706.         malloc_strcpy(&ptr, empty_string);
  707.     else
  708.         malloc_strcpy(&ptr, get_server_nickname(window->server));
  709.     return (ptr);
  710. }
  711.  
  712. static    char    *
  713. status_server(window)
  714.     Window    *window;
  715. {
  716.     char    *ptr = NULL,
  717.         *rest,
  718.         *name;
  719.  
  720.     if (connected_to_server != 1)
  721.     {
  722.         if (window->server != -1)
  723.         {
  724.             if (server_format)
  725.             {
  726.                 name = get_server_name(window->server);
  727.                 if ((rest = (char *) index(name, '.')) != NULL)
  728.                 {
  729.                     if (is_number(name))
  730.                         sprintf(buffer, server_format,
  731.                             name);
  732.                     else
  733.                     {
  734.                         *rest = '\0';
  735.                         sprintf(buffer, server_format,
  736.                             name);
  737.                         *rest = '.';
  738.                     }
  739.                 }
  740.                 else
  741.                     sprintf(buffer, server_format, name);
  742.             }
  743.             else
  744.                 *buffer = '\0';
  745.         }
  746.         else
  747.             strcpy(buffer, "No Server");
  748.     }
  749.     else
  750.         *buffer = '\0';
  751.     malloc_strcpy(&ptr, buffer);
  752.     return (ptr);
  753. }
  754.  
  755. static    char    *
  756. status_query_nick(window)
  757.     Window    *window;
  758. {
  759.     char    *ptr = (char *) 0;
  760.  
  761.     if (window->query_nick && query_format)
  762.     {
  763.         sprintf(buffer, query_format, window->query_nick);
  764.         malloc_strcpy(&ptr, buffer);
  765.     }
  766.     else
  767.         malloc_strcpy(&ptr, empty_string);
  768.     return (ptr);
  769. }
  770.  
  771. static    char    *
  772. status_right_justify(window)
  773.     Window    *window;
  774. {
  775.     char    *ptr = (char *) 0;
  776.  
  777.     malloc_strcpy(&ptr, "\f");
  778.     return (ptr);
  779. }
  780.  
  781. static    char    *
  782. status_notify_windows(window)
  783.     Window    *window;
  784. {
  785.     char    refnum[10];
  786.     int    doneone = 0;
  787.     char    *ptr = (char *) 0;
  788.     int    flag = 1;
  789.     char    buf2[81];
  790.     TravInfo ti;
  791.  
  792.     if (get_int_var(SHOW_STATUS_ALL_VAR) ||
  793.         window == window->screen->current_window)
  794.     {
  795.         *buf2='\0';
  796.         while ((window = traverse_all_windows(&flag, &ti)) != NULL)
  797.         {
  798.             if (window->miscflags & WINDOW_NOTIFIED)
  799.             {
  800.                 if (!doneone)
  801.                 {
  802.                     doneone++;
  803.                     sprintf(refnum, "%d", window->refnum);
  804.                 }
  805.                 else
  806.                     sprintf(refnum, ",%d", window->refnum);
  807.                 strmcat(buf2, refnum, 81);
  808.             }
  809.         }
  810.     }
  811.     if (doneone && notify_format)
  812.     {
  813.         sprintf(buffer, notify_format, buf2);
  814.         malloc_strcpy(&ptr, buffer);
  815.     }
  816.     else
  817.         malloc_strcpy(&ptr, empty_string);
  818.     return ptr;
  819. }
  820.  
  821. static    char    *
  822. status_clock(window)
  823.     Window    *window;
  824. {
  825.     char    *ptr = (char *) 0;
  826.  
  827.     if ((get_int_var(CLOCK_VAR) && clock_format)  &&
  828.         (get_int_var(SHOW_STATUS_ALL_VAR) ||
  829.         (window == window->screen->current_window)))
  830.     {
  831.         sprintf(buffer, clock_format, update_clock(GET_TIME));
  832.         malloc_strcpy(&ptr, buffer);
  833.     }
  834.     else
  835.         malloc_strcpy(&ptr, empty_string);
  836.     return (ptr);
  837. }
  838.  
  839. static    char    *
  840. status_mode(window)
  841.     Window    *window;
  842. {
  843.     char    *ptr = (char *) 0,
  844.         *mode;
  845.  
  846.     if (window->current_channel)
  847.     {
  848.         mode = get_channel_mode(window->current_channel,window->server);
  849.         if (mode && *mode && mode_format)
  850.         {
  851.             sprintf(buffer, mode_format, mode);
  852.             malloc_strcpy(&ptr, buffer);
  853.             return (ptr);
  854.         }
  855.     }
  856.     malloc_strcpy(&ptr, empty_string);
  857.     return (ptr);
  858. }
  859.  
  860.  
  861. static    char    *
  862. status_umode(window)
  863.     Window    *window;
  864. {
  865.     char    *ptr = (char *) 0;
  866.     char    localbuf[10];
  867.     char    *c;
  868.  
  869.     if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR)
  870.         && (window->screen->current_window != window))
  871.         malloc_strcpy(&ptr, empty_string);
  872.     else
  873.     {
  874.         c = localbuf;
  875.         if (get_server_flag(window->server, USER_MODE_I))
  876.             *c++ = 'i';
  877.         if (get_server_operator(window->server))
  878.             *c++ = 'o';
  879.         if (get_server_flag(window->server, USER_MODE_S))
  880.             *c++ = 's';
  881.         if (get_server_flag(window->server, USER_MODE_W))
  882.             *c++ = 'w';
  883.         *c++ = '\0';
  884.         if (*localbuf!='\0')
  885.         {
  886.             sprintf(buffer, umode_format, localbuf);
  887.             malloc_strcpy(&ptr, buffer);
  888.         }
  889.         else
  890.             malloc_strcpy(&ptr, empty_string);
  891.     }
  892.     return (ptr);
  893. }
  894.  
  895. static    char    *
  896. status_chanop(window)
  897.     Window    *window;
  898. {
  899.     char    *ptr = (char *) 0,
  900.         *text;
  901.  
  902.     if (window->current_channel &&
  903.         get_channel_oper(window->current_channel, window->server) &&
  904.         (text = get_string_var(STATUS_CHANOP_VAR)))
  905.         malloc_strcpy(&ptr, text);
  906.     else
  907.         malloc_strcpy(&ptr, empty_string);
  908.     return (ptr);
  909. }
  910.  
  911.  
  912. static    char    *
  913. status_hold_lines(window)
  914.     Window    *window;
  915. {
  916.     char    *ptr = (char *) 0;
  917.     int    num;
  918.     char    localbuf[40];
  919.  
  920.     num = window->held_lines - window->held_lines%10;
  921.     if (num)
  922.     {
  923.         sprintf(localbuf, "%d", num);
  924.         sprintf(buffer, hold_lines_format, localbuf);
  925.         malloc_strcpy(&ptr, buffer);
  926.     }
  927.     else
  928.         malloc_strcpy(&ptr, empty_string);
  929.     return (ptr);
  930. }
  931.  
  932. static    char    *
  933. status_channel(window)
  934.     Window    *window;
  935. {
  936.     int    num;
  937.     char    *ptr,
  938.         channel[IRCD_BUFFER_SIZE + 1];
  939.  
  940.     if (window->current_channel)
  941.     {
  942.         if (get_int_var(HIDE_PRIVATE_CHANNELS_VAR) &&
  943.             is_channel_mode(window->current_channel,
  944.                 MODE_PRIVATE | MODE_SECRET))
  945.             ptr = "*private*";
  946.         else
  947.             ptr = window->current_channel;
  948.         strmcpy(channel, ptr, IRCD_BUFFER_SIZE);
  949.         if ((num = get_int_var(CHANNEL_NAME_WIDTH_VAR)) &&
  950.             (strlen(channel) > num))
  951.             channel[num] = (char) 0;
  952.         /* num = atoi(channel); */
  953.         ptr = (char *) 0;
  954.         sprintf(buffer, channel_format, channel);
  955.         malloc_strcpy(&ptr, buffer);
  956.     }
  957.     else
  958.     {
  959.         ptr = (char *) 0;
  960.         malloc_strcpy(&ptr, empty_string);
  961.     }
  962.     return (ptr);
  963. }
  964.  
  965. static    char    *
  966. status_mail(window)
  967.     Window    *window;
  968. {
  969.     char    *ptr = (char *) 0,
  970.         *number;
  971.  
  972.     if ((get_int_var(MAIL_VAR) && (number = check_mail()) && mail_format) &&
  973.         (get_int_var(SHOW_STATUS_ALL_VAR) ||
  974.         (window == window->screen->current_window)))
  975.     {
  976.         sprintf(buffer, mail_format, number);
  977.         malloc_strcpy(&ptr, buffer);
  978.     }
  979.     else
  980.         malloc_strcpy(&ptr, empty_string);
  981.     return (ptr);
  982. }
  983.  
  984. static    char    *
  985. status_insert_mode(window)
  986.     Window    *window;
  987. {
  988.     char    *ptr = (char *) 0,
  989.     *text;
  990.  
  991.     text = empty_string;
  992.     if (get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR)
  993.         || (window->screen->current_window == window)))
  994.     {
  995.         if ((text = get_string_var(STATUS_INSERT_VAR)) == (char *) 0)
  996.             text = empty_string;
  997.     }
  998.     malloc_strcpy(&ptr, text);
  999.     return (ptr);
  1000. }
  1001.  
  1002. static    char    *
  1003. status_overwrite_mode(window)
  1004.     Window    *window;
  1005. {
  1006.     char    *ptr = (char *) 0,
  1007.     *text;
  1008.  
  1009.     text = empty_string;
  1010.     if (!get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR)
  1011.         || (window->screen->current_window == window)))
  1012.     {
  1013.         if ((text = get_string_var(STATUS_OVERWRITE_VAR)) == (char *) 0)
  1014.         text = empty_string;
  1015.     }
  1016.     malloc_strcpy(&ptr, text);
  1017.     return (ptr);
  1018. }
  1019.  
  1020. static    char    *
  1021. status_away(window)
  1022.     Window    *window;
  1023. {
  1024.     char    *ptr = (char *) 0,
  1025.     *text;
  1026.  
  1027.     if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR)
  1028.         && (window->screen->current_window != window))
  1029.         malloc_strcpy(&ptr, empty_string);
  1030.     else
  1031.     {
  1032.         if (server_list[window->server].away &&
  1033.                 (text = get_string_var(STATUS_AWAY_VAR)))
  1034.             malloc_strcpy(&ptr, text);
  1035.         else
  1036.             malloc_strcpy(&ptr, empty_string);
  1037.     }
  1038.     return (ptr);
  1039. }
  1040.  
  1041. static    char    *
  1042. status_user0(window)
  1043.     Window    *window;
  1044. {
  1045.     char    *ptr = (char *) 0,
  1046.     *text;
  1047.  
  1048.     if ((text = get_string_var(STATUS_USER_VAR)) &&
  1049.         (get_int_var(SHOW_STATUS_ALL_VAR) ||
  1050.         (window == window->screen->current_window)))
  1051.         malloc_strcpy(&ptr, text);
  1052.     else
  1053.         malloc_strcpy(&ptr, empty_string);
  1054.     return (ptr);
  1055. }
  1056.  
  1057. static  char    *
  1058. status_user1(window)
  1059.     Window  *window;
  1060. {
  1061.         char    *ptr = (char *) 0,
  1062.         *text;
  1063.  
  1064.         if ((text = get_string_var(STATUS_USER1_VAR)) &&
  1065.             (get_int_var(SHOW_STATUS_ALL_VAR) ||
  1066.             (window == window->screen->current_window)))
  1067.                 malloc_strcpy(&ptr, text);
  1068.         else
  1069.                 malloc_strcpy(&ptr, empty_string);
  1070.         return (ptr);
  1071. }
  1072.  
  1073. static  char    *
  1074. status_user2(window)
  1075.     Window  *window;
  1076. {
  1077.         char    *ptr = (char *) 0,
  1078.         *text;
  1079.  
  1080.         if ((text = get_string_var(STATUS_USER2_VAR)) &&
  1081.             (get_int_var(SHOW_STATUS_ALL_VAR) ||
  1082.             (window == window->screen->current_window)))
  1083.                 malloc_strcpy(&ptr, text);
  1084.         else
  1085.                 malloc_strcpy(&ptr, empty_string);
  1086.         return (ptr);
  1087. }
  1088.  
  1089. static  char    *
  1090. status_user3(window)
  1091.     Window  *window;
  1092. {
  1093.         char    *ptr = (char *) 0,
  1094.         *text;
  1095.  
  1096.         if ((text = get_string_var(STATUS_USER3_VAR)) &&
  1097.             (get_int_var(SHOW_STATUS_ALL_VAR) ||
  1098.             (window == window->screen->current_window)))
  1099.                 malloc_strcpy(&ptr, text);
  1100.         else
  1101.                 malloc_strcpy(&ptr, empty_string);
  1102.         return (ptr);
  1103. }
  1104.  
  1105. static    char    *
  1106. status_hold(window)
  1107.     Window    *window;
  1108. {
  1109.     char    *ptr = (char *) 0,
  1110.     *text;
  1111.  
  1112.     if (window->held && (text = get_string_var(STATUS_HOLD_VAR)))
  1113.         malloc_strcpy(&ptr, text);
  1114.     else
  1115.         malloc_strcpy(&ptr, empty_string);
  1116.     return (ptr);
  1117. }
  1118.  
  1119. static    char    *
  1120. status_oper(window)
  1121.     Window    *window;
  1122. {
  1123.     char    *ptr = (char *) 0,
  1124.     *text;
  1125.  
  1126.     if (get_server_operator(window->server) &&
  1127.             (text = get_string_var(STATUS_OPER_VAR)) &&
  1128.             (get_int_var(SHOW_STATUS_ALL_VAR) ||
  1129.             connected_to_server != 1 || 
  1130.             (window->screen->current_window == window)))
  1131.         malloc_strcpy(&ptr, text);
  1132.     else
  1133.         malloc_strcpy(&ptr, empty_string);
  1134.     return (ptr);
  1135. }
  1136.  
  1137. static    char    *
  1138. status_window(window)
  1139.     Window    *window;
  1140. {
  1141.     char    *ptr = (char *) 0,
  1142.     *text;
  1143.  
  1144.     if ((text = get_string_var(STATUS_WINDOW_VAR)) &&
  1145.         (number_of_windows() > 1) && (window->screen->current_window == window))
  1146.         malloc_strcpy(&ptr, text);
  1147.     else
  1148.         malloc_strcpy(&ptr, empty_string);
  1149.     return (ptr);
  1150. }
  1151.  
  1152. static    char    *
  1153. status_refnum(window)
  1154.     Window    *window;
  1155. {
  1156.     char    *ptr = (char *) 0;
  1157.  
  1158.     if (window->name)
  1159.         malloc_strcpy(&ptr, window->name);
  1160.     else
  1161.     {
  1162.         sprintf(buffer, "%u", window->refnum);
  1163.         malloc_strcpy(&ptr, buffer);
  1164.     }
  1165.     return (ptr);
  1166. }
  1167.  
  1168. static    char    *
  1169. status_version(window)
  1170.     Window    *window;
  1171. {
  1172.     char    *ptr = (char *) 0;
  1173.  
  1174.     if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR)
  1175.         && (window->screen->current_window != window))
  1176.         malloc_strcpy(&ptr, empty_string);
  1177.     else
  1178.     {
  1179.         malloc_strcpy(&ptr, irc_version);
  1180.     }
  1181.     return (ptr);
  1182. }
  1183.  
  1184.  
  1185. static    char    *
  1186. status_null_function(window)
  1187.     Window    *window;
  1188. {
  1189.     char    *ptr = (char *) 0;
  1190.  
  1191.     malloc_strcpy(&ptr, empty_string);
  1192.     return (ptr);
  1193. }
  1194.  
  1195. /*
  1196.  * pass an already allocated char array with n bits, and this
  1197.  * gets rid of nasty unprintables.
  1198.  */
  1199. static    void
  1200. status_make_printable(str, n)
  1201.     unsigned char    *str;
  1202.     int n;
  1203. {
  1204.     unsigned char    *s;
  1205.     int    pos;
  1206.     define_big_buffer(buffer);
  1207.  
  1208.     if (!str || !*str)
  1209.     {
  1210.         free_big_buffer(buffer);
  1211.         return;
  1212.     }
  1213.  
  1214.     bzero(buffer, BIG_BUFFER_SIZE);
  1215.     for (pos = 0, s = str; s && pos < BIG_BUFFER_SIZE && pos < n; s++)
  1216.     {
  1217.         if (translation)
  1218.             *s = transToClient[*s];
  1219.         if (*s < 32)
  1220.         {
  1221.             switch(*s)
  1222.             {
  1223.             case UND_TOG:
  1224.             case ALL_OFF:
  1225.             case REV_TOG:
  1226.             case BOLD_TOG:
  1227.                 buffer[pos++] = *s;
  1228.                 break;
  1229.             default:
  1230.                 buffer[pos++] = REV_TOG;
  1231.                 buffer[pos++] = (*s & 0x7f) | 0x40;
  1232.                 buffer[pos++] = REV_TOG;
  1233.                 break;
  1234.             }
  1235.         }
  1236.         else if ((u_char) 0x7f == *s)
  1237.         {
  1238.             buffer[pos++] = REV_TOG;
  1239.             buffer[pos++] = '?';
  1240.             buffer[pos++] = REV_TOG;
  1241.         }
  1242.         else
  1243.             buffer[pos++] = *s;
  1244.     }
  1245.     buffer[pos] = '\0';
  1246.     strncpy(str, buffer, pos);
  1247.     free_big_buffer(buffer);
  1248. }
  1249.